package lk.icta.core.web.action;

import lk.icta.common.dto.WorkBenchItem;
import lk.icta.common.web.action.BaseAction;
import lk.icta.core.entity.LandApplication;
import lk.icta.core.entity.WorkflowTask;
import lk.icta.core.service.WorkflowService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.EnumSet;
import java.util.List;

/**
 * @author Mahesha Kalpanie
 */
public class WorkflowAction extends BaseAction {

    private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);

    private final WorkflowService workflowService;

    private List<WorkBenchItem> workBenchItemList;
    private List<LandApplication> landApplicationList;
    private String workflowAction;
    private WorkflowTask workflowTask;
    private int editMode;
    private int alienationMethodId;

    public WorkflowAction(WorkflowService workflowService) {
        this.workflowService = workflowService;
    }

    public String loadAppList() {
        logger.debug("Load Land Application List : {}  ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.loadAppList(user, workflowTask);
            logger.debug("Load Land Application List size : {} ", landApplicationList.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String loadAppListUseAlienationMethod() {
        logger.debug("Load Land Application List UseAlienationMethod : {}  ", user.getUsername());
        logger.debug("Load Land Application List UseAlienationMethod workflow task: {} alenationMethodId: {} ", workflowTask, alienationMethodId);
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.loadAppListUseAlienationMethod(user, workflowTask, alienationMethodId);
            logger.debug("Load Land Application List size : {} ", landApplicationList.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String loadRejectedAppList() {
        logger.debug("Load Land Application List : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.loadRejectedAppList(user);
            //landApplicationList = workflowService.loadWorkBench(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String loadDetailedApplicationListToBeApproved() {
        logger.debug("Load detailed Land Application List to be approved : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.getApplicationsByState(user, WorkflowTask.DETAILED_FORM_DATA_ENTRY);
            //landApplicationList = workflowService.loadWorkBench(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String loadLandAllocatedApplicationList() {
        logger.debug("Load detailed Land Application List to be approved : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.getApplicationsByState(user, WorkflowTask.LAND_ALLOCATED);
            //landApplicationList = workflowService.loadWorkBench(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String loadLandAllocationApprovedApplicationList() {
        logger.debug("Load detailed Land Application List to be approved : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.getApplicationsByState(user, WorkflowTask.LAND_ALLOCATION_APPROVED);
            //landApplicationList = workflowService.loadWorkBench(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String loadAppListBeforeAlienate() {
        logger.debug("Load Land Application List : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.loadApprovedDetailedAppList(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String loadFinalizedAppList() {
        logger.debug("Load Land Application List : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.loadAppListBeforeAlienation(user, editMode);
            // landApplicationList = workflowService.loadFinalizedAppList(user, editMode);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String loadListToBeCompleted() {
        logger.debug("Load Land Application List : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            landApplicationList = workflowService.loadAppListBeforeAlienation(user, editMode);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String getFinalizedApplicationList() {
        logger.debug("Load Finalized Land Application List by : {} ", user.getUsername());
        try {
            EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.INTERVIEW_COMPLETED,
                    WorkflowTask.OBJECTION_HANDLING_APPROVED);
            landApplicationList = workflowService.getApplicationsByStateSet(user, stateSet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String getObjectionHandlingApplicationList() {
        logger.debug("Load Objection Handling Application List by : {} ", user.getUsername());
        EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.INTERVIEW_COMPLETED,
                WorkflowTask.OBJECTION_DATA_ENTRY);
        landApplicationList = workflowService.getApplicationsByStateSet(user, stateSet);
        return SUCCESS;
    }

    public String getObjectionHandlingApprovedApplicationList() {
        logger.debug("Load Objection Handling Approved Application List by : {} ", user.getUsername());
        landApplicationList = workflowService.getApplicationsByState(user,
                WorkflowTask.OBJECTION_HANDLING_COMPLETED);
        return SUCCESS;
    }

    public String getsaveAttachedApplicationList() {
        logger.debug("Load AttachedApplicationList Application List by : {} ", user.getUsername());
        landApplicationList = workflowService.getApplicationsByState(user,
                WorkflowTask.SIGNED_PRINTED_ALIENATION_DOCUMENT);
        return SUCCESS;
    }

    public String getInformRecipientApplicationList() {
        logger.debug("Load Inform Recipient Application List by : {} ", user.getUsername());
        landApplicationList = workflowService.getApplicationsByState(user,
                WorkflowTask.SIGNED_ALIENATION_DOCUMENT_APPROVED);
        return SUCCESS;
    }

    public String loadWorkBench() {
        /*
        logger.debug("-------------------image extractor");
        File jpegFile = new File("c:\\myImage.jpg");
        logger.debug("-------------------image extractor2");
        try {
            logger.debug("-------------------image extractor3");
            Metadata metadata = ImageMetadataReader.readMetadata(jpegFile);
            logger.debug("-------------------image extractor4");

// obtain the Exif directory
            Directory directory = metadata.getDirectory(ExifSubIFDDirectory.class);
            GpsDirectory gpsDirectory = metadata.getDirectory(GpsDirectory.class);
            logger.debug("-------------------image extractor5");

// query the tag's value
            Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
           // double longitude = gpsDirectory.getDoubleObject(GpsDirectory.TAG_GPS_LONGITUDE);
           // double latitute = gpsDirectory.getDoubleObject(GpsDirectory.TAG_GPS_LATITUDE);

            double lat = 0.0;
            double lon = 0.0;
            double alt = 0.0;
            boolean error = false;

            logger.debug("-------------------image extractor6");
            logger.debug("date -------------------{} ", date.toString());

            ////////////////////////////
            Rational latpart[] = gpsDirectory.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE);
            Rational lonpart[] = gpsDirectory.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
            String northing = gpsDirectory.getString(GpsDirectory.TAG_GPS_LATITUDE_REF);
            String easting = gpsDirectory.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF);

            double latsign = 1.0d;
            if (northing.equalsIgnoreCase("S")) {
                latsign = -1.0d;
            }
            double lonsign = 1.0d;
            if (easting.equalsIgnoreCase("W")) {
                lonsign = -1.0d;
            }
            lat = (Math.abs(latpart[0].doubleValue()) + latpart[1].doubleValue() / 60.0d + latpart[2].doubleValue() / 3600.0d) * latsign;
            lon = (Math.abs(lonpart[0].doubleValue()) + lonpart[1].doubleValue() / 60.0d + lonpart[2].doubleValue() / 3600.0d) * lonsign;

            logger.debug("latitude ------------------- {}", lat);
            logger.debug("longitude ------------------- {}", lon);

            if (Double.isNaN(lat) || Double.isNaN(lon)) {
                error = true;
            }

        } catch (ImageProcessingException ip) {
            ip.printStackTrace();
        } catch (IOException me) {
            me.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }    */

        logger.debug("Loading Workbench : {} ", user.getUsername());
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            workBenchItemList = workflowService.loadWorkBench(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public List<WorkBenchItem> getWorkBenchItemList() {
        return workBenchItemList;
    }

    public void setWorkBenchItemList(List<WorkBenchItem> workBenchItemList) {
        this.workBenchItemList = workBenchItemList;
    }

    public List<LandApplication> getLandApplicationList() {
        return landApplicationList;
    }

    public void setLandApplicationList(List<LandApplication> landApplicationList) {
        this.landApplicationList = landApplicationList;
    }

    public String getWorkflowAction() {
        return workflowAction;
    }

    public void setWorkflowAction(String workflowAction) {
        this.workflowAction = workflowAction;
    }

    public int getEditMode() {
        return editMode;
    }

    public void setEditMode(int editMode) {
        this.editMode = editMode;
    }

    public WorkflowTask getWorkflowTask() {
        return workflowTask;
    }

    public void setWorkflowTask(WorkflowTask workflowTask) {
        this.workflowTask = workflowTask;
    }

    public int getAlienationMethodId() {
        return alienationMethodId;
    }

    public void setAlienationMethodId(int alienationMethodId) {
        this.alienationMethodId = alienationMethodId;
    }
}
